package com.multi.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.*;

public class ExecutorDemo {


    public static void main(String[] args) throws InterruptedException {

        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            list.add(String.valueOf(i));
        }

        // 验证 new ThreadPoolExecutor.CallerRunsPolicy() 拒绝策略
        // 当任务数超过队列容量时，CallerRunsPolicy 会让调用者线程（即主线程）来执行任务，从而减缓任务提交的速度，避免任务丢失。
        // 如果线程池中的线程空闲下来，那后续的任务会被线程池中的线程处理。依次循环
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy());

        System.out.println("数量为: " + list.size());
        System.out.println("开始处理任务");

        Map<String,String> resultMap = new ConcurrentHashMap<>();
        Random random = new Random();
        list.forEach(item -> {
            threadPoolExecutor.execute(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(random.nextInt(100));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                System.err.println("处理任务: " + item + " , 当前线程: " + Thread.currentThread().getName());
                resultMap.put(item, item);
            });
        });

        threadPoolExecutor.shutdown();

        // 等待所有任务完成。如果不加这段代码，主线程会在 .shutdown(); 之后立即执行，实际结果发现任务没完成就打印了结果数量
        while (!threadPoolExecutor.awaitTermination(500, TimeUnit.MILLISECONDS)) {
            System.out.println("线程池未在500毫秒内完全终止，继续等待...");
        }

        System.out.println("所有任务处理完成");
        System.out.println("结果数量: " + resultMap.size());
    }
}
